﻿namespace com.game.Public.PoolManager
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using UnityEngine;

    public class SpawnPoolsDict : IEnumerable, IDictionary<string, SpawnPool>, ICollection<KeyValuePair<string, SpawnPool>>, IEnumerable<KeyValuePair<string, SpawnPool>>
    {
        private Dictionary<string, SpawnPool> _pools = new Dictionary<string, SpawnPool>();

        internal void Add(SpawnPool spawnPool)
        {
            if (this.ContainsKey(spawnPool.poolName))
            {
                Debug.LogError(string.Format("A pool with the name '{0}' already exists. This should only happen if a SpawnPool with this name is added to a scene twice.", spawnPool.poolName));
            }
            else
            {
                this._pools.Add(spawnPool.poolName, spawnPool);
            }
        }

        public void Add(KeyValuePair<string, SpawnPool> item)
        {
            string message = "SpawnPools add themselves to PoolManager.Pools when created, so there is no need to Add() them explicitly. Create pools using PoolManager.Pools.Create() or add a SpawnPool component to a GameObject.";
            throw new NotImplementedException(message);
        }

        public void Add(string key, SpawnPool value)
        {
            string message = "SpawnPools add themselves to PoolManager.Pools when created, so there is no need to Add() them explicitly. Create pools using PoolManager.Pools.Create() or add a SpawnPool component to a GameObject.";
            throw new NotImplementedException(message);
        }

        private bool assertValidPoolName(string poolName)
        {
            string str = poolName.Replace("Pool", string.Empty);
            if (str != poolName)
            {
                Debug.LogWarning(string.Format("'{0}' has the word 'Pool' in it. This word is reserved for GameObject defaul naming. The pool name has been changed to '{1}'", poolName, str));
                poolName = str;
            }
            if (this.ContainsKey(poolName))
            {
                Debug.Log(string.Format("A pool with the name '{0}' already exists", poolName));
                return false;
            }
            return true;
        }

        public void Clear()
        {
            string message = "Use PoolManager.Pools.DestroyAll() instead.";
            throw new NotImplementedException(message);
        }

        public bool Contains(KeyValuePair<string, SpawnPool> item)
        {
            string message = "Use PoolManager.Pools.Contains(string poolName) instead.";
            throw new NotImplementedException(message);
        }

        public bool ContainsKey(string poolName)
        {
            return this._pools.ContainsKey(poolName);
        }

        private void CopyTo(KeyValuePair<string, SpawnPool>[] array, int arrayIndex)
        {
            string message = "PoolManager.Pools cannot be copied";
            throw new NotImplementedException(message);
        }

        public SpawnPool Create(string poolName)
        {
            GameObject obj2 = new GameObject(poolName + "Pool");
            return obj2.AddComponent<SpawnPool>();
        }

        public SpawnPool Create(string poolName, GameObject owner)
        {
            SpawnPool pool;
            if (!this.assertValidPoolName(poolName))
            {
                return null;
            }
            string name = owner.gameObject.name;
            try
            {
                owner.gameObject.name = poolName;
                pool = owner.AddComponent<SpawnPool>();
            }
            finally
            {
                owner.gameObject.name = name;
            }
            return pool;
        }

        public bool Destroy(string poolName)
        {
            SpawnPool pool;
            if (!this._pools.TryGetValue(poolName, out pool))
            {
                Debug.LogError(string.Format("PoolManager: Unable to destroy '{0}'. Not in PoolManager", poolName));
                return false;
            }
            UnityEngine.Object.Destroy(pool.gameObject);
            this._pools.Remove(pool.poolName);
            return true;
        }

        public void DestroyAll()
        {
            foreach (KeyValuePair<string, SpawnPool> pair in this._pools)
            {
                UnityEngine.Object.Destroy(pair.Value);
            }
            this._pools.Clear();
        }

        public IEnumerator<KeyValuePair<string, SpawnPool>> GetEnumerator()
        {
            return this._pools.GetEnumerator();
        }

        internal bool Remove(SpawnPool spawnPool)
        {
            if (!this.ContainsKey(spawnPool.poolName))
            {
                Debug.LogWarning(string.Format("PoolManager: Unable to remove '{0}'. Pool not in PoolManager", spawnPool.poolName));
                return false;
            }
            this._pools.Remove(spawnPool.poolName);
            return true;
        }

        public bool Remove(KeyValuePair<string, SpawnPool> item)
        {
            string message = "SpawnPools can only be destroyed, not removed and kept alive outside of PoolManager. There are only 2 legal ways to destroy a SpawnPool: Destroy the GameObject directly, if you have a reference, or use PoolManager.Destroy(string poolName).";
            throw new NotImplementedException(message);
        }

        public bool Remove(string poolName)
        {
            string message = "SpawnPools can only be destroyed, not removed and kept alive outside of PoolManager. There are only 2 legal ways to destroy a SpawnPool: Destroy the GameObject directly, if you have a reference, or use PoolManager.Destroy(string poolName).";
            throw new NotImplementedException(message);
        }

        void ICollection<KeyValuePair<string, SpawnPool>>.CopyTo(KeyValuePair<string, SpawnPool>[] array, int arrayIndex)
        {
            string message = "PoolManager.Pools cannot be copied";
            throw new NotImplementedException(message);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this._pools.GetEnumerator();
        }

        public override string ToString()
        {
            string[] array = new string[this._pools.Count];
            this._pools.Keys.CopyTo(array, 0);
            return string.Format("[{0}]", string.Join(", ", array));
        }

        public bool TryGetValue(string poolName, out SpawnPool spawnPool)
        {
            return this._pools.TryGetValue(poolName, out spawnPool);
        }

        public int Count
        {
            get
            {
                return this._pools.Count;
            }
        }

        private bool IsReadOnly
        {
            get
            {
                return true;
            }
        }

        public SpawnPool this[string key]
        {
            get
            {
                SpawnPool pool;
                try
                {
                    pool = this._pools[key];
                }
                catch (KeyNotFoundException)
                {
                    throw new KeyNotFoundException(string.Format("A Pool with the name '{0}' not found. \nPools={1}", key, this.ToString()));
                }
                return pool;
            }
            set
            {
                string message = "Cannot set PoolManager.Pools[key] directly. SpawnPools add themselves to PoolManager.Pools when created, so there is no need to set them explicitly. Create pools using PoolManager.Pools.Create() or add a SpawnPool component to a GameObject.";
                throw new NotImplementedException(message);
            }
        }

        public ICollection<string> Keys
        {
            get
            {
                string message = "If you need this, please request it.";
                throw new NotImplementedException(message);
            }
        }

        bool ICollection<KeyValuePair<string, SpawnPool>>.IsReadOnly
        {
            get
            {
                return true;
            }
        }

        public ICollection<SpawnPool> Values
        {
            get
            {
                string message = "If you need this, please request it.";
                throw new NotImplementedException(message);
            }
        }
    }
}

